package com.share.thread.future;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author caifan
 * @since 2022/7/15
 */
public class CompletionServiceDemo01 {

    private List<Integer> prices = new ArrayList<>();

    public static void main(String[] args) {
        CompletionServiceDemo01 demo01 = new CompletionServiceDemo01();
        System.out.println(demo01.getPrice());
    }

    public Integer getPrice() {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);
        // 创建CompletionService
        CompletionService<Integer> cs = new ExecutorCompletionService<>(executor);
        // 异步向电商S1询价
        cs.submit(()->getPriceByS1());
        // 异步向电商S2询价
        cs.submit(()->getPriceByS2());
        // 异步向电商S3询价
        cs.submit(()->getPriceByS3());
        // 将询价结果异步保存到数据库
        // 并计算最低报价
        AtomicReference<Integer> m = new AtomicReference<>(Integer.MAX_VALUE);
        for (int i=0; i<3; i++) {
            executor.execute(()->{
                Integer r = null;
                try {
                    r = cs.take().get();
                } catch (Exception e) {}
                prices.add(r);
                m.set(Integer.min(m.get(), r));
            });
        }
        return m.get();
    }

    private Integer getPriceByS1() {
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 300;
    }

    private Integer getPriceByS2() {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 100;
    }

    private Integer getPriceByS3() {
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 200;
    }
}
